Angular একটি শক্তিশালী এবং স্কেলেবল ফ্রেমওয়ার্ক, যা শুধুমাত্র বেসিক ফিচার নয়, বরং অনেক এডভান্সড ফিচার এবং টপিকসও সরবরাহ করে। এসব এডভান্সড ফিচার Angular অ্যাপ্লিকেশনকে আরও ফিচার-প্যাকড, কার্যকরী এবং পারফরম্যান্সে উন্নত করে তোলে। এই টপিকগুলো আপনাকে Angular-এর গভীরে যেতে সহায়তা করবে।
1. Angular Universal (Server-Side Rendering - SSR)
Angular Universal Angular এর একটি ফিচার যা Server-Side Rendering (SSR) সমর্থন করে। SSR এর মাধ্যমে আপনার অ্যাপ্লিকেশন সার্ভার সাইডে রেন্ডার হয়ে ক্লায়েন্ট সাইডে পাঠানো হয়, যা প্রথম লোডিং সময় কমায় এবং SEO (Search Engine Optimization)-এ সাহায্য করে।
ফায়দা:
- প্রথম লোড দ্রুত হয়।
- SEO র্যাঙ্কিং উন্নত হয়।
- ব্যবহারের জন্য সার্ভারে HTML প্রি-রেন্ডার করা হয়।
ইনস্টলেশন এবং কনফিগারেশন:
ng add @nguniversal/express-engine
2. Dynamic Component Loading
Angular-এ Dynamic Component Loading এর মাধ্যমে আপনি runtime এ নতুন কম্পোনেন্ট তৈরি এবং রেন্ডার করতে পারেন। এটি খুবই কার্যকর যখন আপনার অ্যাপ্লিকেশনে ডাইনামিক কন্টেন্ট প্রয়োজন হয়।
উদাহরণ:
import { ComponentFactoryResolver, ViewContainerRef } from '@angular/core';
@Component({
selector: 'app-dynamic-component',
template: `<ng-template #container></ng-template>`
})
export class DynamicComponent {
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef | undefined;
constructor(private resolver: ComponentFactoryResolver) {}
loadComponent() {
const factory = this.resolver.resolveComponentFactory(SomeComponent);
this.container?.clear();
this.container?.createComponent(factory);
}
}
3. State Management (NgRx / Akita / NGXS)
Angular অ্যাপ্লিকেশনে State Management খুবই গুরুত্বপূর্ণ, বিশেষত বড় অ্যাপ্লিকেশনে যেখানে অনেক জটিল স্টেট পরিবর্তন ঘটে। NgRx, Akita, এবং NGXS হল কিছু জনপ্রিয় লাইব্রেরি যেগুলো Redux এর মত স্টেট ম্যানেজমেন্ট প্যাটার্ন ফলো করে।
- NgRx: এটি একটি RxJS-ভিত্তিক স্টেট ম্যানেজমেন্ট লাইব্রেরি যা Store, Actions, Reducers, এবং Effects ধারণা ব্যবহার করে।
- Akita: সহজ এবং খুব কম কোডে স্টেট ম্যানেজমেন্ট সমাধান।
- NGXS: Angular এর জন্য একটি আরও সহজ ও declarative স্টেট ম্যানেজমেন্ট লাইব্রেরি।
উদাহরণ:
ng add @ngrx/store
4. Dependency Injection (DI) Advanced Techniques
Angular-এ Dependency Injection (DI) একটি অত্যন্ত গুরুত্বপূর্ণ ফিচার। এটি অ্যাপ্লিকেশনের বিভিন্ন সার্ভিস এবং কম্পোনেন্টে অবজেক্ট ইনজেক্ট করার জন্য ব্যবহৃত হয়। Advanced DI টপিকসের মধ্যে multi-providers, factory providers, injectable decorators, এবং optional dependencies অন্তর্ভুক্ত রয়েছে।
multi-provider example:
providers: [
{ provide: APP_CONFIG, useValue: config },
{ provide: APP_CONFIG, useValue: anotherConfig, multi: true }
]
5. Custom Validators and Async Validators
Custom Validators তৈরি করা Angular ফর্মের জন্য অনেক গুরুত্বপূর্ণ। আপনি আপনার প্রয়োজনে কাস্টম ভ্যালিডেটর তৈরি করতে পারেন, যা সার্ভারের সাথে অ্যাসিঙ্ক্রোনাস চেকও করতে পারে।
Custom Validator:
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
export function forbiddenNameValidator(name: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const forbidden = control.value === name;
return forbidden ? { forbiddenName: { value: control.value } } : null;
};
}
6. RxJS Advanced Operators
RxJS ব্যবহার Angular অ্যাপ্লিকেশনের জন্য একটি অত্যন্ত শক্তিশালী টুল, যা asynchronous data streams এবং events ম্যানেজ করার জন্য ব্যবহৃত হয়। Advanced RxJS অপারেটর যেমন switchMap, mergeMap, concatMap, catchError, এবং debounceTime নিয়ে কাজ করার মাধ্যমে আপনি অ্যাপ্লিকেশনকে আরও কার্যকরী করতে পারেন।
উদাহরণ:
import { of } from 'rxjs';
import { switchMap, catchError } from 'rxjs/operators';
this.http.get('/api/data')
.pipe(
switchMap(data => of(data)),
catchError(error => of('Error Occurred'))
)
.subscribe(result => console.log(result));
7. Progressive Web App (PWA)
Angular এ Progressive Web App (PWA) তৈরি করার মাধ্যমে আপনি আপনার অ্যাপ্লিকেশনকে একটি offline-first, installable এবং reliable অ্যাপ্লিকেশন হিসেবে পরিণত করতে পারেন। PWA ব্যবহারকারীদের জন্য আরও উন্নত ব্যবহারকারীর অভিজ্ঞতা (UX) এবং পারফরম্যান্স প্রদান করে।
PWA ইনস্টলেশন:
ng add @angular/pwa
8. Angular Elements
Angular Elements এর মাধ্যমে আপনি Angular কম্পোনেন্টকে একটি স্ট্যান্ডার্ড web component হিসেবে রূপান্তর করতে পারেন, যা অন্য যেকোনো ওয়েব অ্যাপ্লিকেশনে ব্যবহার করা যেতে পারে। এটি বিশেষ করে যখন আপনার Angular অ্যাপ্লিকেশন একটি বড় সিস্টেমের অংশ হয়ে থাকে তখন খুবই কার্যকর।
Angular Element Example:
import { Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { MyComponent } from './my.component';
@NgModule({
declarations: [MyComponent],
imports: [BrowserModule],
providers: [],
bootstrap: []
})
export class AppModule {
constructor(private injector: Injector) {
const el = createCustomElement(MyComponent, { injector });
customElements.define('my-component', el);
}
ngDoBootstrap() {}
}
9. Angular CLI Advanced Commands
Angular CLI-এর কিছু অ্যাডভান্সড কমান্ড যেমন ng build --prod, ng serve --hmr, ng update ইত্যাদি আপনার অ্যাপ্লিকেশন তৈরিতে আরও কার্যকরী হতে সাহায্য করে।
HMR (Hot Module Replacement):
ng serve --hmr
10. Angular Performance Optimization
Angular অ্যাপ্লিকেশনের পারফরম্যান্স অপটিমাইজ করতে কিছু পদ্ধতি রয়েছে:
- Change Detection Strategy:
OnPushব্যবহার করা। - Lazy Loading: মডিউলগুলোকে আলাদাভাবে লোড করা।
- TrackBy function: Angular রেন্ডারিং ইফিসিয়েন্সি বাড়াতে।
- Web Workers: ব্যাকগ্রাউন্ড থ্রেডে প্রসেসিং করা।
- AOT Compilation: Ahead-of-Time কম্পাইলেশন সক্ষম করা।
এগুলো হল Angular-এর কিছু গুরুত্বপূর্ণ এডভান্সড টপিকস, যেগুলো অ্যাপ্লিকেশনের স্কেল, পারফরম্যান্স এবং নিরাপত্তা উন্নত করতে সাহায্য করে।
Angular-এর Change Detection হল একটি গুরুত্বপূর্ণ প্রক্রিয়া যা Angular অ্যাপ্লিকেশনের UI-কে আপডেট রাখে যখন ডেটা পরিবর্তিত হয়। Angular দ্বারা ব্যবহৃত Change Detection Strategy দুটি প্রধানভাবে ব্যবহৃত হয়: Default এবং OnPush।
Change Detection কি?
Change Detection হল Angular-এর একটি প্রক্রিয়া যার মাধ্যমে Angular জানে কখন DOM আপডেট করতে হবে। Angular-এর Change Detection মূলত দুটি কাজ করে:
- কম্পোনেন্টের ডেটা চেক করা – Angular জানে কোন ডেটা পরিবর্তিত হয়েছে এবং সেগুলি UI তে রিফ্লেক্ট করে।
- UI আপডেট করা – যখন Angular জানতে পারে যে কোনো ডেটা পরিবর্তিত হয়েছে, তখন এটি UI আপডেট করে।
Angular-এর Change Detection ডিফল্টভাবে Default Strategy ব্যবহার করে, যা সমস্ত কম্পোনেন্টের ডেটার ওপর নজর রাখে। তবে, কনফিগারেশনে কিছু পরিবর্তন করলে আপনি OnPush Strategy ব্যবহার করতে পারেন, যা কিছু ক্ষেত্রে পারফরম্যান্স উন্নত করতে সাহায্য করে।
Default Change Detection Strategy
Default Change Detection Strategy হল Angular-এর ডিফল্ট কৌশল, যেখানে Angular সমস্ত কম্পোনেন্টের সমস্ত প্রোপার্টি পরিবর্তন সনাক্ত করে এবং DOM আপডেট করে। এই কৌশলটি প্রতিটি কম্পোনেন্টের প্রতি চেক করার জন্য একটু বেশি ভারী হতে পারে, বিশেষ করে বড় অ্যাপ্লিকেশনগুলির জন্য।
Default Strategy-তে Change Detection
- Angular সবসময় Component বা Directive-এর প্রতি পরিবর্তন মনিটর করে। অর্থাৎ, এটি চেক করে যে কোনো input property পরিবর্তিত হয়েছে কি না।
- যদি কোন ডেটা পরিবর্তিত হয়, Angular ঐ কম্পোনেন্টের উপর Change Detection চালায় এবং DOM আপডেট করে।
- এই প্রক্রিয়াটি ঘনঘন হয়, যার ফলে এটি বড় অ্যাপ্লিকেশনে পারফরম্যান্স সমস্যার সৃষ্টি করতে পারে।
@Component({
selector: 'app-default',
templateUrl: './default.component.html',
changeDetection: ChangeDetectionStrategy.Default
})
export class DefaultComponent {
data: string = "Hello, World!";
}
এখানে ChangeDetectionStrategy.Default ব্যবহার করা হয়েছে, যা Angular-কে বলে দেয় যে, কম্পোনেন্টের উপর automatically চেক করতে হবে।
OnPush Change Detection Strategy
OnPush Change Detection Strategy হল একটি অপটিমাইজড কৌশল যা Angular-এর Change Detection প্রক্রিয়াকে আরও কার্যকরী করে তোলে, বিশেষ করে বড় অ্যাপ্লিকেশনগুলির জন্য। যখন একটি কম্পোনেন্ট OnPush কৌশল ব্যবহার করে, Angular কেবলমাত্র তখনই Change Detection চালায় যখন:
- Input Property পরিবর্তিত হয়।
- Event (যেমন, Click বা Submit) ঘটে।
- Observable বা Promise এর মান পরিবর্তিত হয়।
এটি Angular-কে পুনরায় চেক করার জন্য কম্পোনেন্টের "input" প্রপার্টি অথবা নির্দিষ্ট পরিবর্তনের উপর নির্ভরশীল করে, তাই এই কৌশলটি অধিক কার্যকরী এবং দ্রুত।
OnPush Strategy-তে Change Detection
- OnPush কৌশল ব্যবহার করলে, Angular শুধুমাত্র তখনই Change Detection চালাবে যখন input property, event, অথবা observable পরিবর্তিত হবে।
- এই কৌশলটি কম্পোনেন্টের পারফরম্যান্স বাড়াতে সাহায্য করে, কারণ Angular কম্পোনেন্টের প্রতি প্রতিটি চেক করার পরিবর্তে শুধুমাত্র নির্দিষ্ট পরিবর্তনগুলো মনিটর করে।
@Component({
selector: 'app-onpush',
templateUrl: './onpush.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnPushComponent {
@Input() data: string = "Hello, OnPush!";
}
এখানে ChangeDetectionStrategy.OnPush ব্যবহার করা হয়েছে, যা Angular কে বলে দেয় যে শুধুমাত্র data প্রপার্টি পরিবর্তিত হলে Change Detection চালানো হবে।
Default vs OnPush: পারফরম্যান্স পার্থক্য
- Default Strategy:
- Angular সকল কম্পোনেন্টের উপর পরিবর্তন চেক করে।
- বড় অ্যাপ্লিকেশনের ক্ষেত্রে অনেক বেশি সিস্টেম রিসোর্স খরচ হতে পারে, কারণ প্রতিটি কম্পোনেন্টের প্রতি পরিবর্তন দেখার জন্য Angular অনেক বার চেক করে।
- OnPush Strategy:
- শুধুমাত্র নির্দিষ্ট কম্পোনেন্টের input property পরিবর্তিত হলে অথবা observable পরিবর্তিত হলে Change Detection চলে।
- এটি ছোট অ্যাপ্লিকেশনগুলোতে ব্যবহৃত হতে পারে এবং বড় অ্যাপ্লিকেশনে পারফরম্যান্সের দিক থেকে অনেক উন্নতি এনে দেয়।
কবে OnPush ব্যবহার করা উচিত?
- ডেটা পরিবর্তন স্পষ্ট থাকলে, অর্থাৎ, যখন কম্পোনেন্টের ইনপুট প্রপার্টি শুধুমাত্র মিউটেশন (mutations) এর মাধ্যমে পরিবর্তিত হয়।
- যখন কম্পোনেন্ট immutable data ব্যবহার করে (যেমন, কোন ডেটা অবজেক্ট বা অ্যারে কখনই সরাসরি পরিবর্তিত হয় না)।
- যখন আপনি জানেন যে Change Detection শুধুমাত্র input বা event পরিবর্তনের সময় ঘটবে।
কবে Default ব্যবহার করা উচিত?
- যদি আপনি complex UI বা dynamic state পরিচালনা করছেন, যেখানে ইনপুট প্রপার্টি বারবার পরিবর্তিত হয়।
- যদি আপনার অ্যাপ্লিকেশনটি ছোট হয় এবং পারফরম্যান্স বিষয়টি এতটা গুরুত্বপূর্ণ না হয়।
সারাংশ
- Default Change Detection-এ Angular সবসময় কম্পোনেন্টের উপর Change Detection চালায়, যা পারফরম্যান্সকে প্রভাবিত করতে পারে বড় অ্যাপ্লিকেশনগুলোতে।
- OnPush Change Detection শুধুমাত্র ইনপুট প্রপার্টি পরিবর্তন, ইভেন্ট অথবা Observable-এ পরিবর্তন হলে Change Detection চালায়, ফলে এটি পারফরম্যান্সের দিক থেকে অনেক কার্যকরী এবং দ্রুত।
এটি বড় অ্যাপ্লিকেশনগুলির জন্য একটি উত্তম পদ্ধতি, যেখানে কম্পোনেন্টগুলো বড় এবং বারবার আপডেট হয়।
Web Workers হল JavaScript-এ মাল্টিথ্রেডিং সমর্থনকারী একটি প্রযুক্তি যা ব্রাউজারে পেছনের থ্রেডে স্ক্রিপ্ট রান করতে সক্ষম করে। এর মাধ্যমে ইউজার ইন্টারফেস বা মেইন থ্রেডে কোনো বিলম্ব বা ব্লকিং ছাড়াই দীর্ঘকাল চলতে থাকা প্রসেসগুলো কার্যকরী করা যায়। Angular এ Web Workers ব্যবহার করলে অ্যাপ্লিকেশন আরও দ্রুত এবং সাড়া দেওয়ার সক্ষম হয়, বিশেষ করে বড় পরিসরের ডেটা প্রসেসিং বা কোনো ভারী কাজের ক্ষেত্রে।
Web Workers এর সুবিধা
- অসীম সমান্তরাল প্রসেসিং: একাধিক কাজ একযোগে চালানো যায়, মেইন থ্রেড ব্লক না হয়ে।
- ব্যবহারকারী ইন্টারফেসের গতিশীলতা: ভারী কাজের কারণে UI হালকা থাকে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত হয়।
- ব্যাকগ্রাউন্ড প্রসেসিং: বড় পরিসরের ডেটা বা গণনা ব্যাকগ্রাউন্ডে চালানো যায়, যার ফলে ইউজার ইন্টারফেস ক্র্যাশ বা স্লো হয় না।
Angular এ Web Workers ব্যবহার করা
Angular অ্যাপ্লিকেশনে Web Workers ব্যবহার করতে Angular CLI সরাসরি সাহায্য করে। এখানে আমরা ধাপে ধাপে দেখব কিভাবে Angular-এ Web Worker ইন্টিগ্রেট করা যায়।
১. Web Worker তৈরি করা
Angular CLI দিয়ে সহজেই Web Worker তৈরি করা যায়। CLI কমান্ড ব্যবহার করলে প্রয়োজনীয় ফাইলগুলো তৈরি হয়ে যায় এবং আপনি সরাসরি Web Worker ব্যবহার করতে পারবেন।
ng generate web-worker worker-name
এটি একটি নতুন Web Worker ফাইল তৈরি করবে, যেমন worker-name.worker.ts।
২. Web Worker কোড
যখন আপনি একটি Web Worker তৈরি করবেন, তখন মূল কাজের লজিক Web Worker ফাইলে থাকবে। উদাহরণস্বরূপ, যদি আপনি একটি গণনা বা বড় ডেটা প্রসেস করতে চান, সেটি Web Worker থ্রেডে করা হবে, যাতে মেইন থ্রেড ব্লক না হয়।
worker-name.worker.ts:
// Web Worker কোড
addEventListener('message', ({ data }) => {
// এখানে আমরা কোনো কাজ করব, যেমন গণনা বা ডেটা প্রসেসিং
const result = data.num * 2; // উদাহরণস্বরূপ, সংখ্যা গুণ করা
postMessage(result); // ফলাফল মেইন থ্রেডে পাঠানো
});
এখানে addEventListener দিয়ে আমরা Web Worker থেকে ডেটা গ্রহণ করছি এবং postMessage দিয়ে ফলাফল মেইন থ্রেডে পাঠাচ্ছি।
৩. মেইন থ্রেডে Web Worker ব্যবহার করা
Web Worker কোড সম্পন্ন হওয়ার পর, মেইন থ্রেডে Web Worker থেকে কাজ করার জন্য Worker API ব্যবহার করতে হবে।
app.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `<h1>Web Worker Example</h1>
<button (click)="runWorker()">Run Web Worker</button>
<p>Result: {{ result }}</p>`,
})
export class AppComponent implements OnInit {
result: number = 0;
private worker: Worker;
ngOnInit() {
// Web Worker ফাইলটি লোড করা
if (typeof Worker !== 'undefined') {
this.worker = new Worker(new URL('./worker-name.worker', import.meta.url));
}
}
runWorker() {
// Web Worker-এ মেসেজ পাঠানো
this.worker.postMessage({ num: 5 });
// Worker থেকে ফলাফল পাওয়া
this.worker.onmessage = ({ data }) => {
this.result = data;
};
}
}
এখানে:
new Worker()দিয়ে আমরা Web Worker তৈরি করেছি এবং এটি একটি ফাইল হিসাবে লোড করছি।postMessage()ব্যবহার করে Web Worker-এ ডেটা পাঠানো হচ্ছে।onmessageইভেন্ট হ্যান্ডলার দিয়ে আমরা Web Worker থেকে প্রাপ্ত ফলাফল গ্রহণ করছি।
৪. Web Worker বন্ধ করা
Web Worker ব্যবহারের পর এটি বন্ধ করে দেওয়া উচিত, যাতে এটি অতিরিক্ত মেমরি ব্যবহার না করে।
ngOnDestroy() {
if (this.worker) {
this.worker.terminate(); // Web Worker বন্ধ করা
}
}
Angular এবং Web Worker এর সুবিধা
- ব্যাকগ্রাউন্ড প্রসেসিং: Angular অ্যাপ্লিকেশনটি মেইন থ্রেডে কাজ করার সময় Web Worker ব্যাকগ্রাউন্ডে দীর্ঘ প্রসেসিং কাজ চালাতে পারে।
- UI রেসপন্সিভ রাখা: UI ইন্টারফেস দ্রুত এবং রেসপন্সিভ থাকে কারণ Web Worker UI থ্রেডে কোনো ধরনের বিলম্ব তৈরি করে না।
- অ্যাপ্লিকেশন পারফরম্যান্স উন্নতি: বড় পরিসরের গণনা বা ডেটা প্রসেসিং করার সময় অ্যাপ্লিকেশনের পারফরম্যান্স অনেক বেড়ে যায়, কারণ সেটা UI থ্রেডে ব্লক না হয়ে ব্যাকগ্রাউন্ডে চলে।
সীমাবদ্ধতা
- ডেটা শেয়ারিং: Web Worker এবং UI থ্রেডের মধ্যে ডেটা শেয়ারিং কিছুটা সীমিত। একমাত্র
postMessage()এবংonmessageইভেন্টের মাধ্যমে ডেটা আদান-প্রদান করা যায়। - ডোম ম্যানিপুলেশন: Web Worker ডিরেক্টলি ডোম ম্যানিপুলেট করতে পারে না, তবে শুধু ব্যাকগ্রাউন্ডে কাজ করার জন্য ব্যবহৃত হয়।
উপসংহার
Angular অ্যাপ্লিকেশনে Web Workers ব্যবহার করে আপনি দীর্ঘ সময় ধরে চলতে থাকা কাজগুলো ব্যাকগ্রাউন্ডে চালাতে পারেন এবং এতে অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত হয়। এটি Angular অ্যাপ্লিকেশনের ইউজার ইন্টারফেসকে দ্রুত এবং রেসপন্সিভ রাখতে সাহায্য করে, বিশেষত যখন আপনার অ্যাপ্লিকেশন বড় পরিসরের ডেটা প্রসেসিং বা গণনার সাথে কাজ করছে।
Angular Universal হল Angular অ্যাপ্লিকেশনগুলির জন্য একটি Server-Side Rendering (SSR) প্রযুক্তি, যা সার্ভার সাইডে HTML রেন্ডারিং করার মাধ্যমে অ্যাপ্লিকেশন লোডিং স্পিড বাড়াতে এবং SEO (Search Engine Optimization) ভালো করার জন্য ব্যবহৃত হয়। এটি মূলত Angular অ্যাপ্লিকেশনকে সার্ভারে রেন্ডার করে, তারপর ক্লায়েন্ট সাইডে অ্যাপ্লিকেশনটি হাইড্রেট (hydrate) করা হয়, যাতে দ্রুত লোড এবং উন্নত SEO সুবিধা পাওয়া যায়।
Angular Universal এর সাহায্যে, অ্যাপ্লিকেশনটি ব্রাউজারে রেন্ডার হওয়ার আগে সার্ভারেই HTML তৈরি হয়, যার ফলে ব্যবহারকারীরা দ্রুত অ্যাপ্লিকেশন দেখতে পান এবং সার্চ ইঞ্জিনের জন্য অ্যাপ্লিকেশনটি আরও "ক্রলেবল" (search engine crawlable) হয়।
Angular Universal এর সুবিধা
- দ্রুত লোডিং: অ্যাপ্লিকেশনটি প্রথমবার লোড হওয়ার সময়, সার্ভারে HTML রেন্ডারিং করার ফলে ব্যবহারকারী দ্রুত কনটেন্ট দেখতে পায়, কারণ ব্রাউজারের কাছে শুধু JSON বা JavaScript ফাইল পাঠানো হয়।
- SEO উন্নতি: সার্ভার সাইড রেন্ডারিং SEO-র জন্য গুরুত্বপূর্ণ, কারণ সার্চ ইঞ্জিনগুলির জন্য অ্যাপ্লিকেশন সহজে ক্রলযোগ্য হয়ে ওঠে। ব্রাউজারের JavaScript রান করার জন্য সার্চ ইঞ্জিনকে অপেক্ষা করতে হয় না।
- Social Media Sharing: Angular Universal সার্ভারে প্রাক-রেন্ডারিংয়ের মাধ্যমে social media platforms (যেমন Facebook, Twitter) এর জন্য প্রাসঙ্গিক metatags তৈরি করতে সাহায্য করে।
- সার্ভার রেন্ডারিং এবং ক্লায়েন্ট হাইড্রেটেশন: Angular Universal অ্যাপ্লিকেশন প্রথমে সার্ভার সাইডে রেন্ডার হয় এবং তারপর ক্লায়েন্ট সাইডে তা হাইড্রেট করা হয়, যা অ্যাপ্লিকেশনকে ইন্টারেক্টিভ এবং ফাস্ট করে তোলে।
Angular Universal সেটআপ
Angular Universal শুরু করার জন্য কিছু নির্দিষ্ট ধাপ অনুসরণ করতে হবে। এখানে আমরা একটি সাধারণ Angular অ্যাপ্লিকেশন সেটআপ করে তা Universal অ্যাপ্লিকেশন হিসেবে কনভার্ট করার প্রক্রিয়া আলোচনা করব।
1. Angular Universal ইনস্টল করা
প্রথমে আপনাকে আপনার Angular অ্যাপ্লিকেশনে Angular Universal যোগ করতে হবে। Angular CLI ব্যবহার করে এটি সহজে ইনস্টল করা যায়।
ng add @nguniversal/express-engine
এই কমান্ডটি Angular Universal এবং Express সার্ভার ইঞ্জিন যুক্ত করবে। এটি কিছু কনফিগারেশন ফাইল এবং সার্ভার সাইডে চলার জন্য প্রয়োজনীয় কোড তৈরি করবে।
2. অ্যাপ্লিকেশন কনফিগারেশন
Angular Universal ইন্সটল করার পর, angular.json ফাইলে কিছু পরিবর্তন করা হবে, এবং একটি নতুন সার্ভার ফাইল তৈরি হবে। নতুন সার্ভার ফাইলটি সাধারণত server.ts নামে তৈরি হয়।
server.ts উদাহরণ:
import 'zone.js/dist/zone-node';
import { enableProdMode } from '@angular/core';
import { ngExpressEngine } from '@nguniversal/express-engine';
import { AppServerModule } from './src/main.server';
import { app } from 'express';
import { join } from 'path';
// Enable production mode
enableProdMode();
// Create an express server
const server = app();
// Set the views directory to the output path for the server
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// Express engine setup
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule
}));
server.set('view engine', 'html');
server.set('views', DIST_FOLDER);
// Serve static files
server.get('*.*', express.static(DIST_FOLDER, {
maxAge: '1y'
}));
// All other routes will be handled by Angular Universal
server.get('*', (req, res) => {
res.render('index', { req });
});
// Start the server
const port = process.env.PORT || 4000;
server.listen(port, () => {
console.log(`Listening on http://localhost:${port}`);
});
3. Server-side module তৈরি
Angular Universal এর জন্য আপনাকে একটি পৃথক server-side module তৈরি করতে হবে। এটি মূলত AppServerModule হবে, যা সার্ভারে রেন্ডারিং করা হয়।
app.server.module.ts উদাহরণ:
import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
@NgModule({
imports: [
AppModule,
ServerModule
],
bootstrap: [AppComponent]
})
export class AppServerModule {}
4. Build এবং Serve
Angular Universal অ্যাপ্লিকেশন তৈরি এবং চালানোর জন্য নিম্নলিখিত কমান্ডগুলি ব্যবহার করতে হবে:
Build Angular Universal অ্যাপ:
npm run build:ssrServe অ্যাপ্লিকেশন:
npm run serve:ssr
এটি অ্যাপ্লিকেশনটি সার্ভারে রেন্ডার করবে এবং আপনার অ্যাপ্লিকেশনকে http://localhost:4000 এ অ্যাক্সেসযোগ্য করে তুলবে।
Angular Universal এর সাহায্যে SEO উন্নতি
সার্ভার সাইড রেন্ডারিং (SSR) দ্বারা, অ্যাপ্লিকেশনটি যখন সার্ভারে রেন্ডার হয়, তখন সমস্ত HTML কনটেন্ট ক্লায়েন্টে পাঠানো হয়। সার্চ ইঞ্জিনগুলি এই HTML কনটেন্টটি সরাসরি পড়ে এবং এটি তাদের ইনডেক্সে যোগ করে, যার ফলে SEO র্যাঙ্কিং উন্নত হয়। সাধারণত, SPA (Single Page Application)-এ যেহেতু JavaScript রান করার জন্য অপেক্ষা করতে হয়, তাই সার্চ ইঞ্জিনগুলি সঠিকভাবে এই অ্যাপ্লিকেশনগুলি ক্রল করতে পারে না। Angular Universal এই সমস্যা সমাধান করে।
সারাংশ
Angular Universal একটি শক্তিশালী প্রযুক্তি যা Angular অ্যাপ্লিকেশনগুলির Server-Side Rendering (SSR) সক্ষম করে। এটি অ্যাপ্লিকেশন লোডিং স্পিড বাড়াতে এবং SEO উন্নত করতে সহায়ক। Angular Universal ব্যবহার করলে অ্যাপ্লিকেশনটি প্রথমে সার্ভারে রেন্ডার হবে এবং পরে ক্লায়েন্টে এটি হাইড্রেট করা হবে। এটি বিশেষভাবে গুরুত্বপূর্ণ যখন আপনার অ্যাপ্লিকেশনটি SEO-র জন্য অপ্টিমাইজড হতে পারে, যেমন ইকমার্স সাইট বা ব্লগ অ্যাপ্লিকেশন।
NgRx হল Angular অ্যাপ্লিকেশনগুলির জন্য একটি জনপ্রিয় স্টেট ম্যানেজমেন্ট লাইব্রেরি। এটি Redux এর একটি Angular উপস্থাপনা, যা অ্যাপ্লিকেশন স্টেট ম্যানেজমেন্টকে আরও সহজ, কার্যকর এবং স্কেলেবল করে তোলে। NgRx মূলত Flux আর্কিটেকচার অনুসরণ করে, যেখানে অ্যাপ্লিকেশনের স্টেট একটি একক কেন্দ্রীয় অবস্থান থেকে পরিচালিত হয়, এবং সেই স্টেটের উপর যেকোনো পরিবর্তন ঘটানোর জন্য নির্দিষ্ট "actions" এবং "reducers" ব্যবহার করা হয়।
NgRx এর মূল ধারণা
NgRx চারটি প্রধান ধারণার উপর ভিত্তি করে কাজ করে:
- Store: অ্যাপ্লিকেশন স্টেটের একটি একক স্থান যেখানে সমস্ত ডেটা রাখা হয়।
- Actions: স্টেট পরিবর্তন করার জন্য অ্যাপ্লিকেশন থেকে পাঠানো সিগন্যাল বা কমান্ড।
- Reducers: Actions এর মাধ্যমে স্টেটে পরিবর্তন করার জন্য নির্দিষ্ট ফাংশন।
- Effects: স্টেট পরিবর্তন করতে API কল বা অন্যান্য অ্যাসিঙ্ক্রোনাস কার্যক্রম পরিচালনা করার জন্য ব্যবহৃত।
NgRx ইন্সটলেশন
এটি Angular প্রজেক্টে ইন্সটল করতে প্রথমে নিচের কমান্ডটি ব্যবহার করুন:
ng add @ngrx/store
এটি আপনার প্রজেক্টে NgRx এর স্টোর লাইব্রেরি ইন্সটল করবে এবং আপনার মডিউলে প্রয়োজনীয় সেটআপ করে দেবে।
NgRx স্টেট ম্যানেজমেন্টের মূল উপাদানসমূহ
১. Store
NgRx Store অ্যাপ্লিকেশনের কেন্দ্রীয় স্টেট ধারণ করে। এটি একটি Immutable অবস্থা (state) যার মধ্যে সমস্ত অ্যাপ্লিকেশন ডেটা থাকবে। অ্যাপ্লিকেশনে যেকোনো পরিবর্তন actions এর মাধ্যমে reducer এ পাঠানো হয় এবং reducer সেই পরিবর্তন করে store আপডেট করে।
স্টোর সেটআপ:
- স্টেট ডিফাইন করুন:
// app.state.ts
export interface AppState {
counter: number;
}
- স্টোর তৈরি করুন:
// app.reducer.ts
import { Action, createReducer, on } from '@ngrx/store';
import { increment, decrement } from './app.actions';
export const initialState: AppState = {
counter: 0,
};
const _counterReducer = createReducer(
initialState,
on(increment, (state) => ({ ...state, counter: state.counter + 1 })),
on(decrement, (state) => ({ ...state, counter: state.counter - 1 }))
);
export function counterReducer(state: AppState | undefined, action: Action) {
return _counterReducer(state, action);
}
২. Actions
Actions হল এমন যেকোনো ইভেন্ট যা অ্যাপ্লিকেশন স্টেট পরিবর্তন করার জন্য ট্রিগার হয়। এটি সাধারণত কমান্ডের মতো কাজ করে এবং নির্দিষ্ট reducer ফাংশন দ্বারা প্রক্রিয়া হয়।
অ্যাকশন তৈরি করুন:
// app.actions.ts
import { createAction } from '@ngrx/store';
export const increment = createAction('[Counter Component] Increment');
export const decrement = createAction('[Counter Component] Decrement');
এখানে, increment এবং decrement হল দুটি অ্যাকশন যা স্টেটের counter ভ্যালু পরিবর্তন করবে।
৩. Reducers
Reducers হল ফাংশন যা অ্যাকশনের ভিত্তিতে স্টেট আপডেট করে। এটি নতুন স্টেটের কপি তৈরি করে এবং অ্যাকশন অনুযায়ী সেই স্টেট পরিবর্তন করে।
Reducers তৈরি করুন:
// app.reducer.ts (আগের উদাহরণ)
export const counterReducer = createReducer(
initialState,
on(increment, (state) => ({ ...state, counter: state.counter + 1 })),
on(decrement, (state) => ({ ...state, counter: state.counter - 1 }))
);
৪. Selectors
Selectors হল ফাংশন যা স্টোর থেকে ডেটা সিলেক্ট করে, এবং কম্পোনেন্টে সেই ডেটা ব্যবহার করা যায়। এটা Store থেকে ডেটা পাওয়ার একটি সহজ উপায়।
Selectors তৈরি করুন:
// app.selectors.ts
import { createSelector } from '@ngrx/store';
import { AppState } from './app.state';
export const selectCounter = (state: AppState) => state.counter;
export const selectCounterValue = createSelector(
selectCounter,
(counter) => counter
);
৫. Effects
NgRx Effects অ্যাসিঙ্ক্রোনাস কার্যকলাপ (যেমন HTTP কল) পরিচালনা করতে ব্যবহৃত হয়। Effects ইন্টারঅ্যাক্ট করে অ্যাকশন ট্রিগার করার মাধ্যমে স্টোরের বাইরে (API কল, টাস্ক, বা অন্যান্য কার্যক্রম) কার্যক্রম পরিচালনা করে।
Effects তৈরি করুন:
// app.effects.ts
import { Injectable } from '@angular/core';
import { Actions, ofType } from '@ngrx/effects';
import { Observable, of } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { increment, decrement } from './app.actions';
@Injectable()
export class AppEffects {
constructor(private actions$: Actions, private store: Store) {}
loadData$ = createEffect(() =>
this.actions$.pipe(
ofType('[App Component] Load Data'),
switchMap(() => {
// API কল বা অন্যান্য কার্যক্রম
return of(increment()); // ডেটা লোডের পর increment action ট্রিগার করুন
})
)
);
}
এখানে, loadData$ অ্যাসিঙ্ক্রোনাস কার্যকলাপটি সম্পাদন করে এবং পরবর্তীতে একটি অ্যাকশন (যেমন increment) পাঠায়।
NgRx Store Module ব্যবহার করা
একবার আপনি অ্যাকশন, reducer, এবং effects তৈরি করলে, আপনাকে Angular মডিউলে NgRx Store এবং Effects মডিউলগুলো অন্তর্ভুক্ত করতে হবে।
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { AppComponent } from './app.component';
import { counterReducer } from './app.reducer';
import { AppEffects } from './app.effects';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
StoreModule.forRoot({ counter: counterReducer }),
EffectsModule.forRoot([AppEffects]),
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
এখানে StoreModule.forRoot এর মাধ্যমে স্টোর সেটআপ করা হচ্ছে এবং EffectsModule.forRoot এর মাধ্যমে অ্যাসিঙ্ক্রোনাস কার্যকলাপ পরিচালনা করার জন্য AppEffects মডিউল যোগ করা হচ্ছে।
NgRx ব্যবহার করে State Management এর সুবিধা
- একক স্টেট ম্যানেজমেন্ট: অ্যাপ্লিকেশনের সমস্ত স্টেট একটি কেন্দ্রীয় স্টোরে রাখা হয়, যা অ্যাপ্লিকেশনকে আরও স্কেলেবল এবং সুসংগঠিত করে।
- ডিবাগিং সহজ: NgRx DevTools ব্যবহার করে স্টেট ম্যানেজমেন্ট সহজে ডিবাগ করা যায়।
- অ্যাসিঙ্ক্রোনাস কার্যকলাপ: Effects এর মাধ্যমে API কল এবং অন্যান্য অ্যাসিঙ্ক্রোনাস কার্যকলাপ কার্যকরভাবে পরিচালিত হয়।
সারাংশ
NgRx একটি শক্তিশালী স্টেট ম্যানেজমেন্ট লাইব্রেরি যা Angular অ্যাপ্লিকেশনগুলির স্টেট ম্যানেজমেন্টকে আরও কার্যকর ও স্কেলেবল করে তোলে। এটি Flux আর্কিটেকচারের উপর ভিত্তি করে তৈরি, যেখানে স্টোর, অ্যাকশন, reducers, এবং effects এর মাধ্যমে স্টেট পরিবর্তন এবং অ্যাসিঙ্ক্রোনাস কার্যকলাপ পরিচালনা করা হয়। NgRx ব্যবহার করার মাধ্যমে অ্যাপ্লিকেশনগুলোতে স্টেট ম্যানেজমেন্টের জটিলতা অনেকটাই কমানো যায়, এবং এটি ডিবাগিংয়ের জন্যও খুবই সহায়ক।
Angular অ্যাপ্লিকেশন তৈরি করার সময়, পারফরম্যান্স একটি গুরুত্বপূর্ণ বিষয়। সঠিক পারফরম্যান্সের মাধ্যমে অ্যাপ্লিকেশন দ্রুত লোড হবে, স্মুথভাবে কাজ করবে, এবং ব্যবহারকারীর জন্য আরও ভালো অভিজ্ঞতা প্রদান করবে। এখানে কিছু গুরুত্বপূর্ণ Angular পারফরম্যান্স অপটিমাইজেশন টেকনিকস দেওয়া হলো যা আপনার অ্যাপ্লিকেশনকে আরও দ্রুত এবং কার্যকরী করতে সাহায্য করবে।
১. Change Detection Strategy
Angular-এর Change Detection মেকানিজম আপনার কম্পোনেন্টগুলির ভিউ আপডেট করার জন্য কাজ করে। তবে, প্রতিটি ইন্টারঅ্যাকশনের জন্য পুরো কম্পোনেন্ট ট্রি চেক করা হলে পারফরম্যান্সে প্রভাব পড়তে পারে।
OnPush Change Detection
OnPush স্ট্রাটেজি ব্যবহার করলে Angular শুধুমাত্র সেই কম্পোনেন্ট বা ভিউ আপডেট করবে যেগুলোর ইনপুট প্রপার্টি বা স্টেট পরিবর্তন হয়েছে। এটি কম্পোনেন্টের পারফরম্যান্স উন্নত করতে সাহায্য করে।
import { Component, ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
changeDetection: ChangeDetectionStrategy.OnPush // Use OnPush strategy
})
export class MyComponent {
// Component code here
}
এটি default স্ট্রাটেজির চেয়ে অনেক দ্রুত কাজ করে, কারণ Angular কম্পোনেন্টের জন্য চেঞ্জ ডিটেকশন চালানোর পরিবর্তে শুধুমাত্র প্রাসঙ্গিক অংশগুলো চেক করে।
২. Lazy Loading
Lazy Loading অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করার জন্য একটি খুবই কার্যকরী পদ্ধতি। এটি আপনার অ্যাপ্লিকেশনকে ছোট ছোট মডিউলগুলোতে ভাগ করে, এবং শুধুমাত্র যখন প্রয়োজন হয় তখনই নির্দিষ্ট মডিউলগুলো লোড হয়।
Lazy Loading কনফিগারেশন
app-routing.module.ts-এ মডিউলগুলো lazy load করতে পারেন:
const routes: Routes = [
{ path: 'feature', loadChildren: () => import('./feature/feature.module').then(m => m.FeatureModule) }
];
এখানে FeatureModule কেবল তখনই লোড হবে যখন ব্যবহারকারী feature রুটে যাবে, অন্যথায় এটি অ্যাপ্লিকেশনের প্রথম লোডিং সময়ে লোড হবে না।
৩. Track By with *ngFor
Angular-এ *ngFor ডিরেক্টিভ ব্যবহার করার সময়, প্রতিটি এলিমেন্টের জন্য DOM রেন্ডারিং এবং চেঞ্জ ডিটেকশন চালানো হয়। যদি আপনার লিস্ট বড় হয়, তবে এটি পারফরম্যান্সে প্রভাব ফেলতে পারে। TrackBy ব্যবহার করে আপনি Angular-কে জানাতে পারেন কোন এলিমেন্টটি পরিবর্তিত হয়েছে, যাতে Angular সঠিকভাবে ডোম আপডেট করতে পারে।
Track By উদাহরণ
<ul>
<li *ngFor="let item of items; trackBy: trackById">{{ item.name }}</li>
</ul>
trackById(index: number, item: any): number {
return item.id; // Return unique identifier for each item
}
এটি Angular-কে জানায় যে কোন আইটেমটি পরিবর্তিত হয়েছে, এবং শুধুমাত্র সেই আইটেমটি পুনরায় রেন্ডার করবে।
৪. Avoiding Implicit Any Types
যখন TypeScript এ any টাইপ ব্যবহার করা হয়, তখন Angular এর টাইপ চেকিং অক্ষম হয়, যার ফলে কম্পাইল টাইমে কোনো ত্রুটি ধরা পড়ে না। এটি পারফরম্যান্সের ওপর নেতিবাচক প্রভাব ফেলতে পারে, কারণ টাইপ সঠিকভাবে নির্ধারণ না করলে, Angular সঠিকভাবে অপটিমাইজ করতে পারে না।
সঠিক টাইপ ব্যবহার
let user: User = { id: 1, name: 'John Doe' };
এটি কম্পাইল টাইমে টাইপ চেকিং চালিয়ে আপনাকে ত্রুটি ধরা পড়তে সাহায্য করে এবং পারফরম্যান্স অপটিমাইজেশনে সহায়তা করে।
৫. AOT (Ahead-of-Time) Compilation
AOT (Ahead-of-Time) Compilation Angular এর একটি ফিচার, যা অ্যাপ্লিকেশনের কোডকে compile করার পরেই ব্রাউজারে পাঠায়। AOT ব্যবহারের ফলে অ্যাপ্লিকেশনটি দ্রুত লোড হয় কারণ ব্রাউজারে কোড কম্পাইল করার প্রয়োজন হয় না। Angular CLI ডিফল্টভাবে AOT সমর্থন করে।
AOT কম্পাইলেশন চালু করা
ng build --prod
এটি AOT কম্পাইলেশন সক্রিয় করে এবং প্রোডাকশন পরিবেশের জন্য অ্যাপ্লিকেশন তৈরি করে, যা পারফরম্যান্স উন্নত করে।
৬. Optimize Bundle Size
অ্যাপ্লিকেশনের bundle size কমাতে হলে কিছু টেকনিক অবলম্বন করা উচিত:
- Tree Shaking: Angular CLI ডিফল্টভাবে tree shaking করে, যার মাধ্যমে অপ্রয়োজনীয় কোড ডিলিট করা হয়।
- Bundle Optimization:
ng build --prodকমান্ডের মাধ্যমে প্রোডাকশন বিল্ড তৈরি করলে এটি কোড মিনিফিকেশন এবং কম্প্রেশন সম্পাদন করে, যা bundle size কমাতে সাহায্য করে।
৭. Server-Side Rendering (SSR) with Angular Universal
Angular Universal হল একটি Angular অ্যাপ্লিকেশনের Server-Side Rendering (SSR) টুল, যা অ্যাপ্লিকেশনের প্রথম লোডিং সময়ে সার্ভার থেকে HTML রেন্ডার করে পাঠায়, ফলে ব্যবহারকারীর জন্য দ্রুত লোডিং এবং SEO উন্নত হয়।
Angular Universal সেটআপ
Angular Universal ব্যবহার করতে Angular CLI দিয়ে নতুন একটি Universal অ্যাপ্লিকেশন তৈরি করা হয়:
ng add @nguniversal/express-engine
এরপর, অ্যাপ্লিকেশনটি সার্ভার থেকে রেন্ডার করার জন্য কনফিগারেশন করা যাবে।
৮. Debouncing and Throttling
কিছু ইভেন্ট (যেমন, ইনপুট ফিল্ডে টাইপ করা, স্ক্রোলিং ইত্যাদি) যদি খুব দ্রুত ঘটে, তবে এটি অ্যাপ্লিকেশনের পারফরম্যান্সে নেতিবাচক প্রভাব ফেলতে পারে। Debouncing এবং Throttling ব্যবহার করে আপনি এই ধরনের ইভেন্টগুলোকে সীমাবদ্ধ করতে পারেন।
RxJS Debounce Example
import { debounceTime } from 'rxjs/operators';
this.searchInput.valueChanges.pipe(
debounceTime(300) // Wait for 300ms after last input
).subscribe(value => {
this.search(value);
});
এটি ইনপুট ফিল্ডে টাইপ করা হলে ইভেন্টগুলোকে ডিবাউন্স করে এবং শুধুমাত্র শেষ টাইপিংয়ের পরে সার্চ ফাংশন কল করবে।
সারাংশ
Angular অ্যাপ্লিকেশনের পারফরম্যান্স অপটিমাইজেশন একটি গুরুত্বপূর্ণ পদক্ষেপ, যা অ্যাপ্লিকেশনটির দ্রুত লোডিং এবং সঠিকভাবে কাজ করার জন্য অপরিহার্য। সঠিক চেঞ্জ ডিটেকশন স্ট্রাটেজি, lazy loading, track by, AOT কম্পাইলেশন, bundle optimization, SSR, এবং debouncing এর মতো টেকনিকগুলি ব্যবহারের মাধ্যমে আপনি Angular অ্যাপ্লিকেশনের পারফরম্যান্স অনেক উন্নত করতে পারবেন।
Read more